home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ELYVER10.ZIP / TUT07NEW.ZIP / TUT7.CPP < prev    next >
Text File  |  1995-01-06  |  41KB  |  911 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. //                                                                         //
  3. // TUTPROG7.CPP - VGA Trainer Program 7 (in Turbo C++ 3.0)                 //
  4. //                                                                         //
  5. // "The VGA Trainer Program" is written by Denthor of Asphyxia. However it //
  6. // was limited to only Pascal in its first run.  All I have done is taken  //
  7. // his original release, translated it to C++ and touched up a few things. //
  8. // I take absolutely no credit for the concepts presented in this code and //
  9. // am NOT the person to ask for help if you are having trouble.            //
  10. //                                                                         //
  11. // Program Notes : This program demonstrates animation.  Several of the    //
  12. //                 functions have been converted to assembler.  This       //
  13. //                 tutorial is a whopper, so just take your time.          //
  14. //                                                                         //
  15. //                 If you are compiling this program from within the       //
  16. //                 Turbo C++ environment, you must go under Options,       //
  17. //                 Debugger, and change the "Program Heap Size" to a value //
  18. //                 132 or greater.  If you are going to be fooling around  //
  19. //                 with the code a bit, I suggest raising this to about    //
  20. //                 150 just to be on the safe side.  You don't have to     //
  21. //                 worry about this if you are compiling command line.     //
  22. //                                                                         //
  23. //                 Just for reference, this is what I use:                 //
  24. //                                                                         //
  25. //                    tcc tut7 -mc -a -G -2 -O                             //
  26. //                                                                         //
  27. //                 The Compact memory model (-mc) seems to provide the     //
  28. //                 best results for this tutorial.  Remember, use this     //
  29. //                 memory model when you have little code (less than 64k)  //
  30. //                 and lots of data.                                       //
  31. //                                                                         //
  32. // Author        : Grant Smith (Denthor) - denthor@beastie.cs.und.ac.za    //
  33. // Translator    : Christopher G. Mann   - r3cgm@dax.cc.uakron.edu         //
  34. //                                                                         //
  35. // Last Modified : January 6, 1995                                         //
  36. //                                                                         //
  37. /////////////////////////////////////////////////////////////////////////////
  38.  
  39. //               //
  40. // INCLUDE FILES //
  41. //               //
  42.  
  43.   #include <alloc.h>
  44.                            // farcalloc()
  45.   #include <conio.h>
  46.                            // clrscr(), getch(), kbhit()
  47.   #include <dos.h>
  48.                            // FP_SEG, geninterrupt()
  49.   #include <iostream.h>
  50.                            // cout, memmove()
  51.   #include <stdlib.h>
  52.                            // abs(), exit(), randomize(), random()
  53.  
  54. //          //
  55. // TYPEDEFS //
  56. //          //
  57.  
  58.   typedef unsigned char byte;
  59.   typedef unsigned int  word;
  60.  
  61. //              //
  62. // TOASTER DATA //
  63. //              //
  64.  
  65. const byte FRAME1[] = {
  66. 0,0,0,0,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,
  67. 7,7,7,7,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,
  68. 5,7,7,7,7,7,7,7,8,8,7,7,7,7,7,7,0,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,
  69. 0,0,0,0,0,5,5,7,7,7,7,7,8,8,7,8,8,7,8,7,8,7,7,7,5,8,8,8,8,5,5,5,5,5,5,5,5,5,5,5,
  70. 5,0,0,0,0,0,0,0,0,0,0,0,5,7,7,7,7,7,7,8,7,7,7,8,7,7,7,7,7,7,0,0,0,0,0,0,8,5,5,5,
  71. 5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,5,7,7,8,8,7,7,8,7,7,8,7,7,7,7,7,0,0,0,0,0,
  72. 0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,5,7,8,8,8,7,7,8,7,7,8,7,7,7,
  73. 7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,5,7,8,8,8,7,7,
  74. 8,8,8,8,8,8,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,
  75. 9,5,7,8,8,8,8,8,7,7,8,8,7,7,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,
  76. 1,1,1,1,9,9,9,9,5,7,7,8,8,8,8,7,7,8,8,7,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
  77. 1,1,0,0,0,1,1,1,1,1,1,1,9,9,9,5,7,8,8,7,7,8,8,7,8,8,8,7,0,0,0,0,0,0,0,0,0,0,0,0,
  78. 0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,5,7,8,8,7,7,7,7,8,8,7,7,7,0,0,0,0,
  79. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,7,8,8,8,8,8,8,8,7,
  80. 7,7,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,7,
  81. 7,7,7,7,7,7,7,7,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,
  82. 1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
  83. 1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
  84. 0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,
  85. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,
  86. 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,
  87. 2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,
  88. 1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,
  89. 4,6,6,6,6,6,6,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
  90. 0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
  91. 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,
  92. 9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,
  93. 9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,
  94. 1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  95. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  96. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  97. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  98. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  99. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  100. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  101. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  102. };
  103.  
  104. const byte FRAME2[] = {
  105. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  106. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  107. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  108. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  109. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  110. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  111. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  112. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  113. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,
  114. 9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,
  115. 1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,
  116. 1,1,0,0,0,1,1,1,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,
  117. 0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
  118. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,
  119. 2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,5,
  120. 5,5,5,5,5,5,5,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,
  121. 1,1,1,2,2,2,2,2,5,5,5,5,5,5,5,5,5,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
  122. 1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,5,5,5,5,5,5,5,5,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
  123. 0,0,0,0,0,5,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,5,5,5,5,5,5,5,5,0,0,0,0,0,
  124. 0,0,0,0,0,0,0,0,0,0,0,0,5,5,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,5,5,5,5,
  125. 5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,
  126. 2,2,2,2,2,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,1,1,1,1,1,1,0,0,0,1,1,1,
  127. 1,1,1,2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,1,7,1,4,
  128. 4,6,6,6,6,6,6,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,
  129. 0,0,0,5,5,1,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,5,5,5,5,5,0,0,
  130. 0,0,0,0,0,0,0,0,0,0,0,5,5,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,9,9,9,9,9,9,9,9,9,9,5,5,
  131. 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,
  132. 9,9,9,9,9,9,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,
  133. 1,1,1,1,9,9,9,9,9,9,9,9,9,9,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,
  134. 1,7,7,1,7,1,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,
  135. 0,0,0,0,0,0,0,5,5,1,7,7,7,1,1,5,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,0,
  136. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,1,1,5,5,5,5,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,
  137. 5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,
  138. 0,0,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  139. 0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  140. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  141. };
  142.  
  143. const byte FRAME3[] = {
  144. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  145. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  146. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  147. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  148. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  149. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  150. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  151. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  152. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,
  153. 9,9,9,9,9,9,9,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,7,7,1,1,1,1,1,1,1,1,1,1,1,
  154. 1,1,1,1,9,9,9,9,9,9,9,9,9,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,7,1,1,1,1,1,
  155. 1,1,0,0,0,1,1,1,1,1,1,1,9,9,9,9,9,9,9,5,5,5,5,5,5,5,5,5,5,5,5,5,0,0,0,0,0,0,0,0,
  156. 0,7,1,1,7,7,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,5,5,5,1,7,7,7,7,5,5,5,5,5,5,
  157. 5,0,0,0,0,0,0,0,7,1,7,7,7,1,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,5,5,1,1,1,7,7,
  158. 1,1,7,5,5,5,5,5,5,5,0,0,0,0,0,0,1,1,7,1,1,7,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,
  159. 2,1,7,7,7,1,7,7,7,7,7,5,5,5,5,5,5,5,5,0,0,0,0,0,1,7,7,7,7,1,1,1,1,1,0,0,0,1,1,1,
  160. 1,1,1,2,2,2,2,2,2,1,7,7,7,7,7,7,7,1,1,5,5,5,5,5,5,5,5,5,0,0,0,0,7,7,1,7,1,7,1,1,
  161. 1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,1,1,1,1,1,1,2,2,5,5,5,5,5,5,5,5,5,5,5,0,0,0,
  162. 7,7,7,7,7,1,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,5,5,5,5,5,5,
  163. 5,5,5,5,5,0,0,0,7,7,0,0,7,7,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,
  164. 2,2,5,5,0,0,5,5,0,5,5,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,1,1,2,2,2,2,2,
  165. 2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,1,1,
  166. 1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,
  167. 4,6,6,6,6,6,6,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,
  168. 0,0,0,0,0,0,1,1,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,
  169. 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,3,3,1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,
  170. 9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,9,9,9,9,
  171. 9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,
  172. 1,1,1,1,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  173. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  174. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  175. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  176. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  177. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  178. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  179. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  180. };
  181.  
  182. //           //
  183. // CONSTANTS //
  184. //           //
  185.  
  186.   const VGA = 0xa000;         // The address of our VGA screen
  187.   const ICON = 30*48;         // This is the size of our pictures
  188.   const NUMTOASTERS = 10;     // The maximum number of toasters we have
  189.   const NUMCIRCLES = 200;     // The number of little circles on the screen
  190.   const TRUE = 1;
  191.   const FALSE = 0;
  192.  
  193. //                     //
  194. // FUNCTION PROTOTYPES //
  195. //                     //
  196.  
  197.   // GENERAL VIDEO TOOLS
  198.   void SetMCGA     ();
  199.   void SetText     ();
  200.   void Cls         (byte Col, word Where);
  201.   void Putpixel    (word X, word Y, byte Col, word Where);
  202.   void WaitRetrace ();
  203.   void Pal         (byte Col, byte  R, byte  G, byte  B);
  204.   void GetPal      (byte Col, byte &R, byte &G, byte &B);
  205.  
  206.   // MID-LEVEL FUNCTIONS
  207.   void SetUpVirtual();
  208.   void ShutDown    ();
  209.   void Flip        (word source, word dest);
  210.   void Putico      (word X, word Y, const byte *sprt, word Where);
  211.   void Funny_line  (int a, int b, int c, int d, word where);
  212.    int sgn         (int a);
  213.   void SetUpScreen ();
  214.   void Rotatepal   ();
  215.   void ScreenTrans (word x, word y);
  216.   void NewToaster  ();
  217.   void Fly         ();
  218.  
  219. //            //
  220. // STRUCTURES //
  221. //        //
  222.  
  223.   struct Toastinfo {
  224.     int      x;
  225.     int      y;
  226.     word     speed;
  227.     word     frame;
  228.     byte     active;
  229.   };
  230.  
  231. //                              //
  232. // GLOBAL VARIABLE DECLARATIONS //
  233. //                              //
  234.  
  235.   byte far *Virscr1=NULL, *Virscr2=NULL;  // Pointers to both virtual screens
  236.   word Vaddr1, Vaddr2;                    // Segments of both virtual screens
  237.   byte ourpal[256][3];                    // A virtual pallette
  238.   Toastinfo toaster[NUMTOASTERS];         // The toaster info
  239.  
  240.  
  241. ///////////////////////////////////////////////////////////////////////////////
  242. //                                                                           //
  243. //                                MAIN FUNCTION                              //
  244. //                                                                           //
  245. ///////////////////////////////////////////////////////////////////////////////
  246.  
  247. void main() {
  248.  
  249.   randomize();    // Make sure that the random() function really is random
  250.   SetUpVirtual(); // Set up the virtual screens and get their segments
  251.  
  252.   clrscr();
  253.   cout
  254.     << "Hello! This program will demonstrate the principals of animation.\n"
  255.     << "The program will firstly generate an arb background screen to a\n"
  256.     << "virtual page, then flip it to the VGA. A toaster will then start\n"
  257.     << "to move across the screen. Note that the background will be restored\n"
  258.     << "after the toaster has passed over it. You may add or remove toasters\n"
  259.     << "by hitting ""+"" or ""-"" respectively. Note that the more frames you\n"
  260.     << "use, usually the better the routine looks. Because of space\n"
  261.     << "restrictions, we only had room for three frames.\n\n";
  262.   cout
  263.     << "The toasters were drawn by Fubar (Pieter Buys) in Autodesk Animator.\n"
  264.     << "I wrote a small little program to convert them into CONSTANTS. See\n"
  265.     << "the main text to find out how to load up AA CEL files directly.\n\n\n";
  266.   cout << "Hit any key to continue...";
  267.   getch();
  268.  
  269.   SetMCGA();
  270.   SetUpScreen();  // Draw background screen to Vaddr1, then flip to VGA
  271.   Fly();          // Make the toasters fly around the screen.
  272.   SetText();
  273.   ShutDown();     // Free the memory taken up by virtual pages
  274.  
  275.   cout
  276.     << "All done. This concludes the seventh sample program in the ASPHYXIA\n"
  277.     << "Training series. You may reach DENTHOR under the names of GRANT\n"
  278.     << "SMITH/DENTHOR/ASPHYXIA on the ASPHYXIA BBS. I am also an avid\n"
  279.     << "Connectix BBS user, which is unfortunatly offline for the moment.\n"
  280.     << "For discussion purposes, I am also the moderator of the Programming\n"
  281.     << "newsgroup on the For Your Eyes Only BBS.\n"
  282.     << "The numbers are available in the main text. You may also write to me at:\n"
  283.     << "             Grant Smith\n"
  284.     << "             P.O. Box 270\n"
  285.     << "             Kloof\n"
  286.     << "             3640\n"
  287.     << "I hope to hear from you soon!\n\n\n";
  288.   cout << "Hit any key to exit...";
  289.   getch();
  290. }
  291.  
  292.  
  293. /////////////////////////////////////////////////////////////////////////////
  294. //                                                                         //
  295. // SetMCGA() - This function gets you into 320x200x256 mode.               //
  296. //                                                                         //
  297. /////////////////////////////////////////////////////////////////////////////
  298.  
  299. void SetMCGA() {
  300.   _AX = 0x0013;
  301.   geninterrupt (0x10);
  302. }
  303.  
  304.  
  305. /////////////////////////////////////////////////////////////////////////////
  306. //                                                                         //
  307. // SetText() - This function gets you into text mode.                      //
  308. //                                                                         //
  309. /////////////////////////////////////////////////////////////////////////////
  310.  
  311. void SetText() {
  312.   _AX = 0x0003;
  313.   geninterrupt (0x10);
  314. }
  315.  
  316.  
  317. /////////////////////////////////////////////////////////////////////////////
  318. //                                                                         //
  319. // Cls() - This clears the screen at location Where to color Col           //
  320. //                                                                         //
  321. /////////////////////////////////////////////////////////////////////////////
  322.  
  323. void Cls(byte Col, word Where) {
  324.   asm {
  325.     push    es           // save ES
  326.     mov     cx, 32000    // this is our loop counter.  we want to clear
  327.                          //   64000 bytes of memory, so why do we use 32000?
  328.                          //   1 word = 2 bytes, and we are moving a word at
  329.                          //   a time
  330.     mov     es, [Where]  // move address in Where to ES
  331.     xor     di, di       // zero out DI
  332.     mov     al, [Col]    // move color to AL
  333.     mov     ah, al       // move color to AH (Remember, will be moving
  334.                          //   a WORDS, so we need two copies
  335.     rep     stosw        // copy AX to Where and drecrement CX by 1
  336.                          //   until CX equals 0
  337.     pop     es           // restore ES
  338.   }
  339. }
  340.  
  341.  
  342. /////////////////////////////////////////////////////////////////////////////
  343. //                                                                         //
  344. // Putpixel() - This puts a pixel on the screen by writing directly to     //
  345. //              memory.                                                    //
  346. //                                                                         //
  347. /////////////////////////////////////////////////////////////////////////////
  348.  
  349. void Putpixel (word X, word Y, byte Col, word Where) {
  350.   asm {
  351.     push    ds           // save DS
  352.     push    es           // save ES
  353.     mov     ax, [Where]  // move segment of Where to AX
  354.     mov     es, ax       // set ES to segment of Where
  355.     mov     bx, [X]      // set BX to X
  356.     mov     dx, [Y]      // set DX to Y
  357.     push    bx           // save BX (our X value)
  358.     mov     bx, dx       // now BX and DX are equal to Y
  359.     mov     dh, dl       // copy DL to DH (multiply Y by 256)
  360.     xor     dl, dl       // zero out DL
  361.     shl     bx, 6        // shift BX left 6 places (multiply Y by 64).
  362.     add     dx, bx       // add BX to DX (Y*64 + Y*256 = Y*320)
  363.     pop     bx           // restore BX (X coordinate)
  364.     add     bx, dx       // add BX to DX (Y*320 + X).  this gives you
  365.                          //   the offset in memory you want
  366.     mov     di, bx       // move the offset to DI
  367.     xor     al, al       // zero out AL
  368.     mov     ah, [Col]    // move value of Col into AH
  369.     mov     es:[di], ah  // move Col to the offset in memory (DI)
  370.     pop     es           // restore ES
  371.     pop     ds           // restore DS
  372.   }
  373. }
  374.  
  375.  
  376. /////////////////////////////////////////////////////////////////////////////
  377. //                                                                         //
  378. // WaitRetrace() - This waits until you are in a Verticle Retrace.         //
  379. //                                                                         //
  380. /////////////////////////////////////////////////////////////////////////////
  381.  
  382. void WaitRetrace() {
  383.  
  384.   asm mov dx,0x03DA
  385.  
  386.   l1: asm {
  387.     in      al,dx;
  388.     and     al,0x08;
  389.     jnz     l1;
  390.   }
  391.   l2: asm {
  392.     in      al,dx;
  393.     and     al,0x08;
  394.     jz      l2;
  395.   }
  396.  
  397. }
  398.  
  399.  
  400. /////////////////////////////////////////////////////////////////////////////
  401. //                                                                         //
  402. // Pal() - This sets the Red, Green, and Blue values of a certain color.   //
  403. //                                                                         //
  404. /////////////////////////////////////////////////////////////////////////////
  405.  
  406. void Pal (byte Col, byte  R, byte  G, byte  B) {
  407.   asm {
  408.     mov     dx, 0x3C8    // load DX with 3C8 (write pallette function)
  409.     mov     al, [Col]    // move color to AL
  410.     out     dx, al       // write DX to the VGA (tell VGA that we want to
  411.                          //   work with the color in AL
  412.     inc     dx           // load DX with 3C9 (write RGB colors)
  413.     mov     al, [R]      // move Red   to AL
  414.     out     dx, al       // write DX to VGA (tell VGA that we want to use
  415.                          //   the Red value in AL
  416.     mov     al, [G]      // move Green to AL
  417.     out     dx, al       // write DX to VGA
  418.     mov     al, [B]      // move Blue  to AL
  419.     out     dx, al       // write DX to VGA
  420.   }
  421. }
  422.  
  423.  
  424. /////////////////////////////////////////////////////////////////////////////
  425. //                                                                         //
  426. // GetPal() - This reads the values of the Red, Green, and Blue values of  //
  427. //            a certain color.  This function uses pass-by-reference.      //
  428. //                                                                         //
  429. /////////////////////////////////////////////////////////////////////////////
  430.  
  431. void GetPal (byte Col, byte &R, byte &G, byte &B) {
  432.  
  433.   byte rr,gg,bb;
  434.  
  435.   asm {
  436.     mov     dx, 0x03C7   // load DX with 3C7 (read pallette function)
  437.     mov     al, [Col]    // move color to AL
  438.     out     dx, al       // write DX to the VGA (tell VGA that we want to
  439.                          //   work with the color in AL
  440.     add     dx, 2        // load DX with 3C9 (read RGB colors)
  441.     in      al, dx       // read Red   to AL
  442.     mov     [rr],al      // copy AL to rr
  443.     in      al, dx       // read Green to AL
  444.     mov     [gg],al      // copy AL to gg
  445.     in      al, dx       // read Blue  to AL
  446.     mov     [bb],al      // copy AL to bb
  447.   }
  448.  
  449.   R = rr;
  450.   G = gg;
  451.   B = bb;
  452.  
  453. }
  454.  
  455.  
  456. /////////////////////////////////////////////////////////////////////////////
  457. //                                                                         //
  458. // SetUpVirtual() - This sets up the memory needed for the virtual screen. //
  459. //                                                                         //
  460. /////////////////////////////////////////////////////////////////////////////
  461.  
  462. void SetUpVirtual() {
  463.  
  464.   Virscr1 = (byte far *) farcalloc(64000,1);
  465.   Virscr2 = (byte far *) farcalloc(64000,1);
  466.  
  467.   // always check to see if enough memory was allocated
  468.   if ((Virscr1 == NULL) || (Virscr2 == NULL)) {
  469.     SetText();
  470.     cout << "Insufficient memory for virtual screens, exiting...";
  471.     free(Virscr1);  // on the off chance that it allocated 1 but not 2,
  472.             // deallocate the first.
  473.     exit(1);
  474.   }
  475.  
  476.   Vaddr1 = FP_SEG(Virscr1);
  477.   Vaddr2 = FP_SEG(Virscr2);
  478.  
  479. }
  480.  
  481.  
  482. /////////////////////////////////////////////////////////////////////////////
  483. //                                                                         //
  484. // ShutDown() - This frees the memory used by the virtual screen.          //
  485. //                                                                         //
  486. /////////////////////////////////////////////////////////////////////////////
  487.  
  488. void ShutDown() {
  489.  
  490. //  free(Virscr1);
  491. //  free(Virscr2);
  492.  
  493. }
  494.  
  495.  
  496. /////////////////////////////////////////////////////////////////////////////
  497. //                                                                         //
  498. // Flip() - This copies the entire screen at "source" to destination.      //
  499. //                                                                         //
  500. /////////////////////////////////////////////////////////////////////////////
  501.  
  502. void Flip(word source, word dest) {
  503.   asm {
  504.     push    ds           // save DS
  505.     mov     ax, [dest]   // copy segment of destination to AX
  506.     mov     es, ax       // set ES to point to destination
  507.     mov     ax, [source] // copy segment of source to AX
  508.     mov     ds, ax       // set DS to point to source
  509.     xor     si, si       // zero out SI
  510.     xor     di, di       // zero out DI
  511.     mov     cx, 32000    // set our counter to 32000
  512.     rep     movsw        // move source to destination by words.  decrement
  513.                          //   CX by 1 each time until CX is 0
  514.     pop     ds           // restore DS
  515.   }
  516. }
  517.  
  518.  
  519. /////////////////////////////////////////////////////////////////////////////
  520. //                                                                         //
  521. // Putico() - This puts an icon, EXCEPT it's color 0 (black) pixels, onto  //
  522. //            the screen "where", at position X,Y                          //
  523. //                                                                         //
  524. /////////////////////////////////////////////////////////////////////////////
  525.  
  526. void Putico(word X, word Y, const byte *sprt, word Where) {
  527.   asm {
  528.     push    ds           // save DS
  529.     push    es           // save ES
  530.     lds     si, [sprt]   // set SI to offset of sprite
  531.     mov     ax, X        // set AX equal to X
  532.     mov     bx, Y        // set BX equal to Y
  533.   }
  534.   _Redraw: asm {
  535.     push    ax           // save AX (X coordinate)
  536.     mov     ax, [Where]  // copy segment of Where to AX
  537.     mov     es, ax       // set ES to segment of Where
  538.     mov     ax, bx       // set AX to BX (X)
  539.     mov     bh, bl       // copy BL to BH (multiply Y by 256)
  540.     xor     bl, bl       // zero out BL
  541.     shl     ax, 6        // multiply AX by 64 (Y * 64)
  542.     add     bx, ax       // add AX to BX (Y*64 + Y*256 = Y*320)
  543.     pop     ax           // restore BX (X coordinate)
  544.     add     ax, bx       // add BX to AX (Y*320 + X).  this gives you
  545.                          //   the offset in memory you want
  546.     mov     di, ax       // move the offset to DI
  547.     mov     dl, 30       // set DL to height of sprite
  548.     xor     ch, ch       // zero out CH
  549.     mov     cl, 48       // set CL to width of sprite
  550.     cld                  // clear direction flag.  if you did not do this,
  551.                          //   the loop would go backward instead of forward
  552.     push    ax           // save AX (offset in memory where you draw)
  553.     mov     ax, cx       // set AX to CX (width)
  554.   }
  555.   _DrawLoop: asm {
  556.     push    di           // save DI (offset in memory where you draw)
  557.     mov     cx, ax       // set CX to AX (width)
  558.   }
  559.   _LineLoop: asm {       // DRAW THE DATA
  560.     mov     bl,byte ptr [si]
  561.                          // load byte of data from sprite to BL
  562.     or      bl, bl       // no effect, but triggers zero flag
  563.     jnz     _Store       // if previous statement did not trigger zero flag
  564.                          //   (BL was not color 0) then jump to _Store
  565.                          //   (write it to the screen).  in the description
  566.                          //   of this function, it said that we would not be
  567.                          //   putting color 0 on the screen, so the next
  568.   }                      //   section skips over the pixel if it was 0.
  569.  
  570.   _NoPaint: asm {        // SKIP OVER COLOR 0
  571.     inc     si           // increment SI (skip to next pixel)
  572.     inc     di           // increment DI (skip to next pixel)
  573.     loop    _LineLoop    // decrement CX and jump to _LineLoop if CX is
  574.                          //   not 0 (end of line)
  575.     jmp     _NextLine    // if CX is 0 (end of line) jump to _NextLine
  576.   }
  577.   _Store: asm {          // COPY THE DATA
  578.     movsb                // move the byte that DS:SI is pointing to into
  579.                          //   ES:DI and increment SI and DI.
  580.     loop    _LineLoop    // decrement CX and jump to _LineLoop if CX is
  581.   }                      //   not 0 (end of line)
  582.  
  583.   _NextLine: asm {       // START A NEW LINE
  584.     pop     di           // restore address of line just drawn
  585.     dec     dl           // decrement DL (height)
  586.     jz      _Exit        // when DL equals 0, you are done drawing the sprite
  587.     add     di, 320      // if not end of sprite, add 320 to DI so that we
  588.                          //   start drawing the sprite on the next line
  589.     jmp     _DrawLoop    // go back to _DrawLoop and start drawing the next
  590.   }                      //   line
  591.  
  592.   _Exit: asm {           // WE ARE DONE DRAWING THE SPRITE
  593.     pop     ax           // restore AX
  594.     pop     es           // restore ES
  595.     pop     ds           // restore DS
  596.   }
  597. }
  598.  
  599.  
  600. /////////////////////////////////////////////////////////////////////////////
  601. //                                                                         //
  602. // sgn() - This function is used by Line() to determine the sign of a long //
  603. //                                                                         //
  604. /////////////////////////////////////////////////////////////////////////////
  605.  
  606. int sgn (int a) {
  607.  
  608.   if (a > 0)  return +1;
  609.   if (a < 0)  return -1;
  610.   return 0;
  611. }
  612.  
  613.  
  614. /////////////////////////////////////////////////////////////////////////////
  615. //                                                                         //
  616. // Funny_line() - This function draws a line from a,b, to c,d on screen    //
  617. //                "where".  After it plots each pixel, it increments a     //
  618. //                color counter for the next pixel.  You may easily alter  //
  619. //                this to be a normal line function, and it will be quite  //
  620. //                a bit faster than the original one I gave you.  This is  //
  621. //                because I replaced all the floats with integers.         //
  622. //                                                                         //
  623. /////////////////////////////////////////////////////////////////////////////
  624.  
  625. void Funny_line (int a, int b, int c, int d, word where) {
  626.  
  627. int i,s,d1x,d1y,d2x,d2y,u,v,m,n,count;
  628.  
  629.   count = 50;
  630.   u = c - a;       // u = x2 - x1  (change in x)
  631.   v = d - b;       // v = y2 - y1  (change in y)
  632.  
  633.   d1x = sgn(u);    // d1x = sign of the change in x
  634.   d1y = sgn(v);    // d1y = sign of the change in y
  635.  
  636.   d2x = sgn(u);    // d2x = sign of the change in x
  637.   d2y = 0;         // d2y = 0
  638.   m = abs(u);      // m = positive change in x
  639.   n = abs(v);      // n = positive change in y
  640.  
  641.   if (m <= n) {
  642.     d2x = 0;       // d2x = 0
  643.     d2y = sgn(v);  // d2y = sign of the change in y
  644.     m = abs(v);    // m = positive change in y
  645.     n = abs(u);    // n = positive change in x
  646.   }
  647.   s = m / 2;       // s = half of the change in x/y
  648.  
  649.   for (i=0;i<m+1;i++) {
  650.     Putpixel(a,b,count,where);   // plot the original x1 and y1
  651.     count++;                     // increment the color
  652.     if (count > 100) count = 50; // if color is out of bounds, reset
  653.     s += n;
  654.     if (s >= m) {
  655.       s -= m;
  656.       a += d1x;
  657.       b += d1y;
  658.     }
  659.     else {
  660.       a += d2x;
  661.       b += d2y;
  662.     }
  663.   }
  664. }
  665.  
  666.  
  667. /////////////////////////////////////////////////////////////////////////////
  668. //                                                                         //
  669. // SetUpScreen() - This procedure sets up the static background to be used //
  670. //                 in the program.                                         //
  671. //                                                                         //
  672. /////////////////////////////////////////////////////////////////////////////
  673.  
  674. void SetUpScreen() {
  675.  
  676.   int x,y,loop1,loop2,loop3;
  677.   const byte circ[5][5] = {{ 0,10,10,10, 0},
  678.                {10,13,12,11,10},
  679.                {10,12,12,11,10},
  680.                {10,11,11,11,10},
  681.                { 0,10,10,10, 0}};
  682.  
  683.   // set the pallette for the toasters and some other things
  684.   Pal (1 ,22,22,22);
  685.   Pal (2 ,45,45,45);
  686.   Pal (3 ,59,59,59);
  687.   Pal (4 ,63,63,27);
  688.   Pal (5 ,39,63, 3);
  689.   Pal (6 ,51,39, 3);
  690.   Pal (7 , 3,27, 3);
  691.   Pal (8 ,15,39,15);
  692.   Pal (9 ,35,35,35);
  693.   Pal (10, 0, 0,40);
  694.   Pal (11,10,10,50);
  695.   Pal (12,20,20,60);
  696.   Pal (13,30,30,63);
  697.  
  698.   // set pallette colors 50-100 to blue values between 13 and 63
  699.   for (loop1 = 50; loop1 < 101; loop1++)
  700.     Pal (loop1,0,0,loop1-37);
  701.  
  702.   // put a copy of the pallette into ourpal[]
  703.   for (loop1 = 0; loop1 < 256; loop1++)
  704.     GetPal (loop1,ourpal[loop1][0],ourpal[loop1][1],ourpal[loop1][2]);
  705.  
  706.   // draw funny lines
  707.   for (loop1 = 0; loop1 < 320; loop1++)
  708.     Funny_line (0,199,loop1,0,Vaddr1);
  709.   for (loop1 = 0; loop1 < 200; loop1++)
  710.     Funny_line (0,199,319,loop1,Vaddr1);
  711.  
  712.   // draw circles
  713.   for (loop1 = 0; loop1 < 200; loop1++) {
  714.     x = random (315);
  715.     y = random (195);
  716.     for (loop2 = 0; loop2 < 5; loop2++)
  717.       for (loop3 = 0; loop3 < 5; loop3++)
  718.       // don't plot a pixel if its color is 0
  719.         if (circ[loop2][loop3] != 0)
  720.           Putpixel(x+loop2,y+loop3,circ[loop2][loop3],Vaddr1);
  721.   }
  722.  
  723.   // Copy the entire screen at Vaddr1, our virtual screen on which we have
  724.   // done all our graphics, onto the screen you see, VGA.
  725.   Flip (Vaddr1,VGA);
  726.   // also make a copy of the virtual screen to Vaddr2
  727.   Flip (Vaddr1,Vaddr2);
  728.  
  729. }
  730.  
  731.  
  732. /////////////////////////////////////////////////////////////////////////////
  733. //                                                                         //
  734. // Rotatepal() - This function rotates the colors between 50 and 100.      //
  735. //                                                                         //
  736. /////////////////////////////////////////////////////////////////////////////
  737.  
  738. void Rotatepal() {
  739.  
  740.   byte temp[3];
  741.   int loop1;
  742.  
  743.   memmove(temp,ourpal[100],3);
  744.   memmove(ourpal[51],ourpal[50],50*3);
  745.   memmove(ourpal[50],temp,3);
  746.   for (loop1 = 50; loop1 < 101; loop1++)
  747.     Pal (loop1,ourpal[loop1][0],ourpal[loop1][1],ourpal[loop1][2]);
  748.  
  749. }
  750.  
  751.  
  752. /////////////////////////////////////////////////////////////////////////////
  753. //                                                                         //
  754. // ScreenTrans() - This is a small function to copy a 30x30 pixel block    //
  755. //                 from coordinates x,y on the Vaddr1 to           //
  756. //                 coordinates x,y on the true vga screen.                 //
  757. //                                                                         //
  758. // ERROR, from Vaddr1 to Vaddr2
  759. /////////////////////////////////////////////////////////////////////////////
  760.  
  761. void ScreenTrans (word x, word y) {
  762.   asm {
  763.     push    ds           // save DS
  764.     push    es           // save ES
  765.     mov     ax,Vaddr1    // set AX to the segment of Virtual Screen 1
  766.     mov     es,ax        // set ES to segment of Vaddr1
  767.     mov     ax,Vaddr2    // set AX to the segment of Virtual Screen 2
  768.     mov     ds,ax        // set DS to segment of Vaddr2
  769.     mov     bx,[x]       // set BX to x
  770.     mov     dx,[y]       // set DX to y
  771.     push    bx           // save x coordinate
  772.     mov     bx, dx       // copy y coordinate to BX
  773.     mov     dh, dl       // multiply y*256
  774.     xor     dl, dl       // zero out DL
  775.     shl     bx, 6        // multiply y*64
  776.     add     dx, bx       // add y*64 to y*256 to get y*320
  777.     pop     bx           // restore x coordinate
  778.     add     bx, dx       // finalize the location
  779.     mov     di, bx       // set DI to offset of Virtual Screen 1
  780.     mov     si, di       // set SI to offset of Virtual Screen 2
  781.     mov     al,60        // I have no idea why this is here.
  782.     mov     bx, 30       // set BX to height of block
  783.   }
  784.   _loop1: asm {
  785.     mov     cx, 24       // set CX to width of block divided by 2
  786.     rep     movsw        // copy the screens and decrement CX by 1 until
  787.                          //   CX is 0
  788.     add     di,0x110     // 320 - 48 = 272 .. or 110 in hex
  789.     add     si,0x110
  790.     dec     bx           // decrease number lines left to draw
  791.     jnz     _loop1       // if not done go back to _loop1
  792.     pop     es           // restore ES
  793.     pop     ds           // restore DS
  794.   }
  795.  
  796. }
  797.  
  798.  
  799. /////////////////////////////////////////////////////////////////////////////
  800. //                                                                         //
  801. // NewToaster() - This adds a new toaster to the screen.                   //
  802. //                                                                         //
  803. /////////////////////////////////////////////////////////////////////////////
  804.  
  805. void NewToaster() {
  806.  
  807.   int loop1 = 0;
  808.  
  809.   do {
  810.     if (toaster[loop1].active == FALSE) {
  811.       toaster[loop1].x = random(200)+70;
  812.       toaster[loop1].y = 0;
  813.       toaster[loop1].active = TRUE;
  814.       toaster[loop1].frame = 1;
  815.       toaster[loop1].speed = random(3)+1;
  816.       loop1 = 10;
  817.     }
  818.     loop1++;
  819.   } while (loop1 < NUMTOASTERS);
  820.  
  821. }
  822.  
  823.  
  824. /////////////////////////////////////////////////////////////////////////////
  825. //                                                                         //
  826. // Fly() - This is the function where we move and put the toasters.        //
  827. //                                                                         //
  828. /////////////////////////////////////////////////////////////////////////////
  829.  
  830. void Fly() {
  831.  
  832.   int loop1,loop2;
  833.   char ch;
  834.  
  835.   for (loop1 = 0; loop1 < NUMTOASTERS; loop1++)
  836.     toaster[loop1].active = FALSE;
  837.  
  838.   ch = '0'; // assign a dummy value to ch
  839.   NewToaster();
  840.  
  841.   do {
  842.     // if a key is pressed...
  843.  
  844.     if (kbhit()) {
  845.       ch = getch();
  846.       // if '+' is pressed, add a toaster
  847.       if (ch == '+') NewToaster();
  848.       // if '-' is pressed, remove a toaster
  849.       if (ch == '-') {
  850.         loop1 = 0; // start with toaster 0
  851.         do {
  852.           // if the loop1 toaster is active
  853.           if (toaster[loop1].active == TRUE) {
  854.             // draw the toaster on the screen
  855.             ScreenTrans(toaster[loop1].x,toaster[loop1].y);
  856.             // then make it false
  857.             toaster[loop1].active = FALSE;
  858.             // break out of the loop
  859.             loop1 = 10;
  860.           }
  861.           // check the next toaster
  862.           loop1++;
  863.         } while (loop1 < NUMTOASTERS);
  864.       }
  865.     }
  866.  
  867.     // if no key was pressed...
  868.  
  869.     for (loop1 = 0; loop1 < NUMTOASTERS; loop1++) {
  870.       if (toaster[loop1].active == TRUE) {
  871.         // Restore the background the toaster was over
  872.         ScreenTrans(toaster[loop1].x,toaster[loop1].y);
  873.         // Move the toaster
  874.         toaster[loop1].x -= toaster[loop1].speed;
  875.         toaster[loop1].y += toaster[loop1].speed;
  876.         // When toaster reaches the edge of the screen, render it inactive
  877.         // and bring a new one into existance.
  878.         if ((toaster[loop1].x < 0) || (toaster[loop1].y > 170)) {
  879.           toaster[loop1].active = FALSE;
  880.           NewToaster();
  881.         }
  882.       }
  883.     }
  884.  
  885.     // Draw all of the toasters
  886.     for (loop1 = 0; loop1 < NUMTOASTERS; loop1++) {
  887.       // ... but only if they are active
  888.       if (toaster[loop1].active == TRUE)
  889.         switch (toaster[loop1].frame) {
  890.         case 1: Putico(toaster[loop1].x,toaster[loop1].y,FRAME1,Vaddr1); break;
  891.         case 2: Putico(toaster[loop1].x,toaster[loop1].y,FRAME3,Vaddr1); break;
  892.         case 3: Putico(toaster[loop1].x,toaster[loop1].y,FRAME2,Vaddr1); break;
  893.         case 4: Putico(toaster[loop1].x,toaster[loop1].y,FRAME3,Vaddr1); break;
  894.         }
  895.       // increment the current frame of the toaster
  896.       toaster[loop1].frame += 1;
  897.       // reset the frame if it gets to 5
  898.       if (toaster[loop1].frame == 5) toaster[loop1].frame = 1;
  899.     }
  900.  
  901.     WaitRetrace();
  902.     Flip(Vaddr1,VGA);
  903.     Rotatepal();
  904.  
  905.     // if the key pressed above was 0 (escape key) then read the escape code
  906.     if (ch == 0) ch = getch();
  907.  
  908.   } while (ch != 27); // if the escape code was 27 (escape key) then exit
  909.  
  910. }
  911.